
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:ali_vod_video/ali_vod_video.dart';
import 'package:ali_vod_video/upload_callback.dart';
import 'package:e_reception_flutter/media_library/media_library_index/bean/video_upload_success_bean.dart';
import 'package:e_reception_flutter/net/net_api.dart';
import 'package:e_reception_flutter/net/server_api.dart';
import 'package:e_reception_flutter/singleton/constant_repository/constant_repository.dart';
import 'package:e_reception_flutter/singleton/user_repository/user_repository.dart';
import 'package:e_reception_flutter/ui/smart_home/event/refresh_smart_home_category_event.dart';
import 'package:e_reception_flutter/ui/smart_home/event/refresh_smart_home_folder_detail_event.dart';
import 'package:e_reception_flutter/ui/smart_home/event/refresh_smart_home_index_event.dart';
import 'package:e_reception_flutter/utils/vg_http_utils.dart';
import 'package:e_reception_flutter/utils/vg_matisse_utils.dart';
import 'package:e_reception_flutter/utils/vg_string_utils.dart';
import 'package:e_reception_flutter/utils/vg_toast_utils.dart';
import 'package:path_provider/path_provider.dart';
import 'package:photo_preview/photo_preview_export.dart';
import 'package:vg_base/vg_base_callback.dart';
import 'package:vg_base/vg_evnet_bus_lib.dart';
import 'package:vg_base/vg_string_util_lib.dart';
import 'package:video_thumbnail/video_thumbnail.dart';
import '../../app_main.dart';
import '../smart_home_upload_service.dart';

///视频上传工具类
class VideoUploadService {
  static VideoUploadService _instance;

  ///通知上传数据变化
  StreamController<List<SmartHomeUploadItemBean>> uploadServiceStream;
  ///正在上传的视频信息集合
  Map<String,List<SmartHomeUploadItemBean>> _uploadingInfoMap;
  ///正在上传视频通知流集合
  Map<String, StreamController<SmartHomeUploadItemBean>> uploadingStreamMap;
  ///上传实例
  Map<String, AliVodVideo> _uploadingInstanceMap;

  VideoUploadService(){
    uploadServiceStream = StreamController.broadcast();
    _uploadingInfoMap = Map();
    uploadingStreamMap = Map();
    _uploadingInstanceMap = Map();
  }

  static VideoUploadService getInstance() {
    if (_instance == null) {
      _instance = new VideoUploadService();
    }
    return _instance;
  }

  List<SmartHomeUploadItemBean> getUploadingInfoList(String shid){
    return _uploadingInfoMap[shid];
  }

  //从所有视频列表中获取某个视频上传的进度
  SmartHomeUploadItemBean getCurrentUploadingInfo(String shid, String id){
    SmartHomeUploadItemBean tempInfo = _uploadingInfoMap[shid]?.where((info) => info?.id == id)?.first;
    return tempInfo;
  }

  void cancelUpload(String id, String path){
    _uploadingInstanceMap[id]?.cancelUploadVideo(id, path);
  }

  void cancelAll(String id){
    _uploadingInstanceMap[id]?.cancelUploadVideoAll();
    _uploadingInfoMap?.values?.forEach((uploadingInfoList) {
      uploadingInfoList.forEach((info) {
        info.status=UploadStatus.stop;
        //通知更新进度
        uploadingStreamMap[info?.id].add(info);
      });
    });
    _uploadingInfoMap?.clear();
    uploadingStreamMap?.clear();
    uploadServiceStream.add(null);
  }

  ///上传
  void upload(SmartHomeUploadItemBean item, String scid, String sfid, String shid,
      String desc, int coverIndex, String title, String mid, String type)async{
    try {
      item = await _decodeVideo(item);
    }
    catch (e) {
      // callback?.onError("处理出现异常");
      print("上传报错:$e");
      return;
    }
    item.progress = 0;
    String id=DateTime.now().toString();
    item.id = id;
    //根据门店id获取正在上传的视频信息列表
    List<SmartHomeUploadItemBean> uploadingInfoList = _uploadingInfoMap[shid];
    if(uploadingInfoList == null){
      uploadingInfoList = List();
    }
    uploadingInfoList.add(item);
    _uploadingInfoMap[shid] = uploadingInfoList;
    uploadServiceStream.add(uploadingInfoList);

    StreamController<SmartHomeUploadItemBean> stream = StreamController.broadcast();
    stream.add(item);
    uploadingStreamMap[id] = stream;
    try {
      uploadSingleVideo(
        item.id,
        item.localUrl,
        UploadCallback(
            onProgress: (progress, id, {String msg}){
              SmartHomeUploadItemBean tempInfo = _uploadingInfoMap[shid]?.where((info) => info?.id == id)?.first;
              if(tempInfo.status != UploadStatus.stop){
                tempInfo.status=UploadStatus.onProgress;
              }
              tempInfo.progress = progress;
              print("进度-------：" + progress.toString() + msg??"");
              //通知更新进度
              uploadingStreamMap[id].add(tempInfo);
            },
            onSuccess: (net, fileSize,coverUrl, videoId, sdVideo, sdStorage)async{
              VideoUploadSuccessBean successBean = new VideoUploadSuccessBean(net, fileSize,coverUrl, videoId, sdVideo, sdStorage);
              item.netUrl = successBean.url;
              item.videoid = successBean.videoid;
              item.folderName = VgMatisseUploadUtils.getVideoPath();
              if (!StringUtils.isEmpty(successBean.fileSize)) {
                item.folderStorage = int.parse(successBean.fileSize);
              }
              // item.sdVideo = successBean.sdVideo;
              // item.sdStorage = successBean.sdStorage;
              // if (StringUtils.isEmpty(successBean.coverUrl)) {
              item.videoNetCover =
              await VgMatisseUploadUtils.uploadSingleImageForFuture(
                  item.videoLocalCover,
                  isNoCompress: false);
              uploadSmartHomeData(item, scid, sfid, shid, desc, coverIndex, title, mid, type);

              // } else {
              //   item.videoNetCover = successBean.coverUrl;
              // }
            },
            onError: (msg){
            },
            onCancel: (String id, String path){
              //根据shid获取当前门店正在上传的视频信息列表
              List<SmartHomeUploadItemBean> uploadingInfoList = _uploadingInfoMap[shid];
              SmartHomeUploadItemBean currentItem = uploadingInfoList?.where((info) => info?.id == id)?.first;
              currentItem.status=UploadStatus.stop;
              //通知更新进度
              uploadingStreamMap[id].add(currentItem);

              //更新当前门店正在上传的视频信息列表
              uploadingInfoList?.remove(uploadingInfoList?.where((info) => info?.id == id)?.first);
              _uploadingInfoMap[shid] = uploadingInfoList;
              //通知此门店上传视频数据的监听stream 进行更新
              uploadServiceStream.add(uploadingInfoList);
              uploadingStreamMap.remove(id);
            }
        ),);

    } catch (e) {
      print("MediaLibraryIndexService上传异常：$e");
    }
  }


  uploadSmartHomeData(SmartHomeUploadItemBean element, String scid, String sfid,
      String shid, String desc, int coverIndex, String title, String mid, String type){
    List<PicListItemBean> picList = new List();
    PicListItemBean picListItemBean = new PicListItemBean(
      picurl: element.getPicUrl()??"",
      linkpic: element.linkCover??"",
      type: element.type??"",
      picname: element.folderName??"",
      picsize: element.getSize()??"",
      picstorage: element.getStorage()??"",
      videotime: element.videoDuration??0,
      videopic: element.videoNetCover??"",
      videoid: element.videoid??"",
      sd_video: element?.sdVideo??"",
      sd_storage: element?.getSDStorage()??"",
      scid: element.getScid()??(scid??""),
      style: element.style??"99",
      backup: element.backup??"",
      picid: element.getPicid(),
    );
    picList.add(picListItemBean);

    String picjson = "";
    if(picList.isNotEmpty){
      picjson = json.encode(picList);
    }
    //接口
    String url;
    Map<String, dynamic> paramsMap;
    if(StringUtils.isEmpty(sfid)){

      url = NetApi.SMART_HOME_PUBLISH;
      paramsMap = {
        "authId": UserRepository.getInstance().authId ?? "",
        "backup": desc ?? "",
        "coversize": picList.elementAt(coverIndex)?.picsize ?? "",
        "coverurl": picList.elementAt(coverIndex)?.getCoverUrl() ?? "",
        "scid": scid ?? "",
        "title": title ?? "",
        "shid": shid ?? "",
        "picjson": picjson ?? "",
        "sysmid": mid ?? "",
        "type": type ?? "",
      };
      print("准备多图上传测试参数: ${paramsMap}");
      VgHttpUtils.post(url,
          params: paramsMap,
          callback: BaseCallback(onSuccess: (val) {
            //根据shid获取当前门店正在上传的视频信息列表
            List<SmartHomeUploadItemBean> uploadingInfoList = _uploadingInfoMap[shid];
            //更新当前门店正在上传的视频信息列表
            uploadingInfoList?.remove(uploadingInfoList?.where((info) => info?.id == element?.id)?.first);
            _uploadingInfoMap[shid] = uploadingInfoList;
            //通知此门店上传视频数据的监听stream 进行更新
            uploadServiceStream.add(uploadingInfoList);




            element.progress = 100;
            //通知更新进度
            uploadingStreamMap[element?.id].add(element);
            uploadingStreamMap.remove(element?.id);
            VgEventBus.global.send(new RefreshSmartHomeCategoryEvent(id: scid));
            VgEventBus.global.send(new RefreshSmartHomeIndexEvent());

          }, onError: (msg) {

            //根据shid获取当前门店正在上传的视频信息列表
            List<SmartHomeUploadItemBean> uploadingInfoList = _uploadingInfoMap[shid];
            //更新当前门店正在上传的视频信息列表
            uploadingInfoList?.remove(uploadingInfoList?.where((info) => info?.id == element?.id)?.first);
            _uploadingInfoMap[shid] = uploadingInfoList;
            //通知此门店上传视频数据的监听stream 进行更新
            uploadServiceStream.add(uploadingInfoList);

            uploadingStreamMap.remove(element?.id);
            VgToastUtils.toast(AppMain.context, "上传失败:" + msg);
          }));
    }else{
      url = NetApi.SMART_HOME_EDIT_FOLDER;
      paramsMap = {
        "authId": UserRepository.getInstance().authId ?? "",
        "backup": desc ?? "",
        "coversize": picList.elementAt(coverIndex)?.picsize ?? "",
        "coverurl": picList.elementAt(coverIndex)?.getCoverUrl() ?? "",
        "scid": scid ?? "",
        "title": title ?? "",
        "shid": shid ?? "",
        "picjson": picjson ?? "",
        "sfid": sfid ?? "",
        "sysmid": mid ?? "",
        "type": type ?? "",
      };
      print("准备多图上传测试参数: ${paramsMap}");
      VgHttpUtils.post(url,
          params: paramsMap,
          callback: BaseCallback(onSuccess: (val) {
            //根据shid获取当前门店正在上传的视频信息列表
            List<SmartHomeUploadItemBean> uploadingInfoList = _uploadingInfoMap[shid];
            //更新当前门店正在上传的视频信息列表
            uploadingInfoList?.remove(uploadingInfoList?.where((info) => info?.id == element?.id)?.first);
            _uploadingInfoMap[shid] = uploadingInfoList;
            //通知此门店上传视频数据的监听stream 进行更新
            uploadServiceStream.add(uploadingInfoList);

            element.progress = 100;
            //通知更新进度
            uploadingStreamMap[element?.id].add(element);
            uploadingStreamMap.remove(element?.id);
            VgEventBus.global.send(new RefreshSmartHomeCategoryEvent(id: scid));
            VgEventBus.global.send(new RefreshSmartHomeIndexEvent());
            VgEventBus.global.send(new RefreshSmartHomeFolderDetailEvent());
          }, onError: (msg) {
            //根据shid获取当前门店正在上传的视频信息列表
            List<SmartHomeUploadItemBean> uploadingInfoList = _uploadingInfoMap[shid];
            //更新当前门店正在上传的视频信息列表
            uploadingInfoList?.remove(uploadingInfoList?.where((info) => info?.id == element?.id)?.first);
            _uploadingInfoMap[shid] = uploadingInfoList;
            //通知此门店上传视频数据的监听stream 进行更新
            uploadServiceStream.add(uploadingInfoList);

            uploadingStreamMap.remove(element?.id);
            VgToastUtils.toast(AppMain.context, "上传失败:" + msg);
          }));
    }
  }


  Future<SmartHomeUploadItemBean> _decodeVideo(
      SmartHomeUploadItemBean item) async {
    if (item == null ||
        item.type == null ||
        StringUtils.isEmpty(item.localUrl)) {
      return null;
    }
    File file = File(item.localUrl);
    if(StringUtils.isEmpty(item.videoLocalCover)){
      Directory rootPath = await getTemporaryDirectory();
      Directory tempDirectory = new Directory('${rootPath.path}/imageTemp');
      if (!tempDirectory.existsSync()) {
        tempDirectory.createSync();
      }
      String tmpVideoCover = await VideoThumbnail.thumbnailFile(
        video: item.localUrl,
        thumbnailPath: tempDirectory?.path,
        imageFormat: ImageFormat.JPEG,
        maxWidth: 1920,
        quality: 100,
      );
      item.videoLocalCover = tmpVideoCover;
    }
    //
    VideoPlayerController videoController = VideoPlayerController.file(file);
    await videoController.initialize();
    item.videoDuration = videoController?.value?.duration?.inSeconds;
    item.folderWidth = videoController?.value?.size?.width?.floor();
    item.folderHeight = videoController?.value?.size?.height?.floor();
    item.folderStorage = file.lengthSync();
    videoController.dispose();
    return item;
  }


  void uploadSingleVideo(String id, String path, UploadCallback callback){
    if(StringUtils.isEmpty(path)){
      callback.onError("路径获取失败");
    }
    if(VgStringUtils.isNetUrl(path)){
      callback.onSuccess(path, "","", "", "", "");
    }
    String cateId = ("http://et.lemontry.com/" ==ServerApi.BASE_URL)?"2061":"2165";
    print("VgMatisseUploadUtils:" + cateId);
    String userData = '{"MessageCallback":{"CallbackURL":"'+ServerApi.BASE_URL+'aliyunvod/transcodingCallback","CallbackType":"http"}, "Extend":"01"}';
    AliVodVideo uploadInstance = new AliVodVideo();
    _uploadingInstanceMap[id] = uploadInstance;
    uploadInstance.uploadVideo(id, cateId, ConstantRepository.of().getTemplateGroupId(),
        ConstantRepository.of().getDefinition(), path, userData, UploadCallback(
            onSuccess: (net, fileSize,coverUrl, videoId, sdVideo, sdStorage){
              _uploadingInstanceMap[id] = null;
              _uploadingInstanceMap.remove(id);
              if(net == null || net == ""){
                callback.onError("数据空");
                print("VgMatisseUploadUtils:数据空");
                return;
              }
              print("VgMatisseUploadUtils:net:" + net);
              callback.onSuccess(net, fileSize,coverUrl, videoId, sdVideo, sdStorage);
            },
            onError: (msg){
              _uploadingInstanceMap[id] = null;
              _uploadingInstanceMap.remove(id);
              print("VgMatisseUploadUtils:onError:" + msg);
              callback.onError(msg);
            },
            onProgress: (progress, id, {String msg}){
              callback.onProgress(progress, id, msg:msg);
            },
            onCancel: (String currentId, String path){
              _uploadingInstanceMap[currentId] = null;
              _uploadingInstanceMap.remove(currentId);
              callback.onCancel(currentId, path);
            }
        ), needProgress: true);
  }

}